package com.oschina.lazy.safe.doublelock;

/**
 * @author zhouyang
 * @Date 2017-08-19 17:31
 * @Description
 * @Version 1.0
 */
public class Singleton {
    private volatile static Singleton singleton;

    private Singleton(){

    }

    public static Singleton getSingleton() {
        /**
         * 虽然看起来确实解决性能的问题,只有第一次创建对象才是同步操作,但其实是有问题的。
         * 主要是singleton = new Singleton()并非是原子操作。
         * JVM大概做以下三步
         * 1.给singleton分配内存
         * 2.调用singleton的构造函数来初始化成员变量
         * 3.将singleton对象指向分配的内存空间
         * 但JVM的编译器存在指令重排序的问题,也就是说2,3步的执行顺序并不能保证,有可能是1-3-2,1-2-3。
         * 如果是1-3-2,3执行完毕但2没有执行完毕,线程2进入这个时候singleton已经不是null但还没有将进行初始化,
         * 线程2将会访问到一个还未有初始化的对象。
         *
         * 使用volatile 禁止指令重排序
         */
        if(singleton == null){
            synchronized (Singleton.class){
                if(singleton == null){
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}
